package bean
{
	import define.DBConst;
	import define.ItemConst;
	
	import flash.data.SQLStatement;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SQLEvent;
	import flash.events.SecurityErrorEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	
	import iris.util.StringProcessor;
	
	import mx.collections.ArrayCollection;
	import mx.utils.StringUtil;
	
	import orm.armory.dao.TblItemProperty_DAO;
	import orm.armory.dao.TblItem_DAO;
	import orm.armory.vo.TblItemPropertyVO;
	import orm.armory.vo.TblItemVO;
	
	public class CollectBean extends EventDispatcher
	{
		
		private var _itemVo:TblItemVO;
		private var _itemPropertyVo:TblItemPropertyVO;
		
		private var _itemDescriptions:ArrayCollection;
		// side: Alliance, Horde
		// icon
		private var _itemAdditionals:Object;
		
		private var _step:int = -1;
		private var _functions:Array;
		
		public function CollectBean(itemVo:TblItemVO):void
		{
			_itemVo = itemVo;
		}
		public function run():void
		{
			_functions = [getItemHtml, downloadIcon, assignItemPropertyVo, assignItemVo, dropTrash, updateDB];
			
			gotoNextStep();
		}
		private function gotoNextStep():void
		{
			_step++;
			// COLLECT_START
			if(_step == 0)
				this.dispatchEvent(new CollectEvent(CollectEvent.COLLECT_START, _itemVo, _itemPropertyVo));
			// COLLECT_FINISH, COLLECT_ERROR
			if(_step > _functions.length - 1)
			{
				if(_itemDescriptions.length > 0)
					this.dispatchEvent(new CollectEvent(CollectEvent.COLLECT_ERROR, _itemVo, _itemPropertyVo, _itemDescriptions.toString()));
				this.dispatchEvent(new CollectEvent(CollectEvent.COLLECT_FINISH, _itemVo, _itemPropertyVo));
			}
			// run
			else
			{
				(_functions[_step] as Function).call(this);
			}
		}
		/**
		 * http://www.wowhead.com/?item=45291
		 */
		private function getItemHtml():void
		{
			var url:String = "http://www.wowhead.com/?item=" + _itemVo.item_id;			
			var loader:URLLoader = new URLLoader();
			loader.addEventListener(Event.COMPLETE, urlCompleteListener);
			loader.addEventListener(ProgressEvent.PROGRESS, urlProgressListener);
			
			loader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, urlEventListener);
			//loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, urlEventListener);
			loader.addEventListener(IOErrorEvent.IO_ERROR, urlEventListener);
			loader.addEventListener(Event.OPEN, urlEventListener);
			loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, urlEventListener);
			
			loader.load(new URLRequest(url));
		}
		private function urlProgressListener(event:ProgressEvent):void
		{
			//trace(_itemVo.item_id + ": " + event.type);
		}
		private function urlEventListener(event:Event):void
		{
			if(event.type == IOErrorEvent.IO_ERROR
				|| event.type == SecurityErrorEvent.SECURITY_ERROR)
				this.dispatchEvent(new CollectEvent(CollectEvent.COLLECT_FINISH, _itemVo, _itemPropertyVo, event.type));
			else if(event.type == Event.OPEN)
				this.dispatchEvent(new CollectEvent(CollectEvent.COLLECT_PROGRESS, _itemVo, _itemPropertyVo, event.type));
			else if(event.type == HTTPStatusEvent.HTTP_RESPONSE_STATUS)
			{
				var message:String = (event as HTTPStatusEvent).status + " - " + (event as HTTPStatusEvent).responseURL				
				this.dispatchEvent(new CollectEvent(CollectEvent.COLLECT_PROGRESS, _itemVo, _itemPropertyVo, message));
			}
		}
		private function urlCompleteListener(event:Event):void
		{
			this.dispatchEvent(new CollectEvent(CollectEvent.COLLECT_PROGRESS, _itemVo, _itemPropertyVo, event.type));
			
			var html:String = (event.target as URLLoader).data;
			
			_itemDescriptions = getItemDescriptions(html);
			_itemAdditionals = getItemAdditionals(html);
			
			gotoNextStep();
		}
		
		private function getItemDescriptions(html:String):ArrayCollection
		{
			var sp:StringProcessor = new StringProcessor(html, true);
			sp.intercept("<table><tr><td><table><tr><td><b class=\"q4\"", 
				"<th style=\"background-position: bottom right\"></th></tr></table>", 
				false, false);
			// (1.22% @ L80).
			// <small>(<a href="javascript:;" onmousedown="return false" onclick="g_setRatingLevel(this,80,18,32)">1.22%&nbsp;@&nbsp;L80</a>)</small>
			sp.drop("<small>", "</small>", false, false, true);
			// Sell Price: <span class="moneygold">4</span> <span class="moneysilver">43</span> <span class="moneycopper">42</span>
			sp.drop("Sell Price: ", "<span", false, true, true);
			sp.drop("<span class=\"moneygold\">", "</span>", false, false, true);
			sp.drop("<span class=\"moneysilver\">", "</span>", false, false, true);
			sp.drop("<span class=\"moneycopper\">", "</span>", false, false, true);
			// Triumphant VanCleef's Battlegear (0/5)
			// VanCleef's Pauldrons of Triumph
			// VanCleef's Legplates of Triumph
			// VanCleef's Helmet of Triumph
			// VanCleef's Gauntlets of Triumph
			// VanCleef's Breastplate of Triumph
			//
			// (2) Set: Your Rupture ability has a chance each time it deals damage to reduce the cost of your next ability by 40 energy.
			// (4) Set: Increases the critical strike chance of your Hemorrhage, Sinister Strike, Backstab, and Mutilate abilities by 5%.
			sp.drop("<a href=\"/?itemset", "</table>", false, false, true);
			// trim
			var itemDescription:String = StringUtil.trim(sp.source);

			var lst:ArrayCollection = new ArrayCollection();
			var line:String;
			while(true)
			{
				try
				{
					line = new StringProcessor(itemDescription).intercept(">", "<", false, false);
				}
				catch (error:Error)
				{
					break;
				}
				line = line.replace(/&nbsp;/g, " "); 
				line = StringUtil.trim(line);
				if(line != "")
					lst.addItem(line);
					
				itemDescription = itemDescription.substr(itemDescription.indexOf(">") + 1);
			}
			// 091123, todo: Combine [Equip:]
			return lst;
		}
		
		private function getItemAdditionals(html:String):Object
		{
			var sp:StringProcessor = new StringProcessor(html, false);
			var s:String;
			var o:Object = {};
			
			// side
			try
			{
				s = sp.intercept("Side: [icon", "/icon]", false, false);
			}
			catch(error:Error)
			{
				s = null;
			}
			if(s != null)
				o.side = new StringProcessor(s).intercept("]", "[", false, false);
			// icon
			o.icon = sp.intercept("ge('ic" + _itemVo.item_id + "').appendChild(Icon.create('", "'", false, false);
			o.icon = (o.icon as String).toLowerCase();
			
			return o;
		}
		private function downloadIcon():void
		{
			var localFile:File = new File(File.desktopDirectory.nativePath + "/iris_asset/item_icon/" + _itemAdditionals.icon + ".jpg");
			if(!localFile.exists)
			{
				var loader:URLLoader = new URLLoader(
					new URLRequest("http://static.wowhead.com/images/icons/large/" + _itemAdditionals.icon + ".jpg"));
				loader.dataFormat = URLLoaderDataFormat.BINARY;
				loader.addEventListener(Event.COMPLETE, iconLoadCompelete);
			}
			gotoNextStep();
		}
		private function iconLoadCompelete(event:Event):void
		{
			var loader:URLLoader = event.target as URLLoader;
			var ba:ByteArray = loader.data as ByteArray;
		
			var localFile:File = new File(File.desktopDirectory.nativePath + "/iris_asset/item_icon/" + _itemAdditionals.icon + ".jpg");
			localFile.parent.createDirectory();
			var fs:FileStream = new FileStream();
			fs.openAsync(localFile, FileMode.WRITE);

			while(ba.bytesAvailable > 0)
				fs.writeByte(ba.readByte());
		}
		private function assignItemPropertyVo():void
		{
			var temporary:String;
			_itemPropertyVo = new TblItemPropertyVO();
			// info_xxx
			_itemPropertyVo.info_item_id = _itemVo.item_id;
			if(_itemAdditionals.side != null)
				_itemPropertyVo.info_side =	_itemAdditionals.side;
			_itemPropertyVo.info_icon = _itemAdditionals.icon;
			_itemPropertyVo.info_item_name = seekPropertyByIndex(0);
			_itemPropertyVo.info_item_level = seekPropertyByTag("Item Level ", "");
			_itemPropertyVo.info_bind_type = translateBindType(seekPropertyByTag("Binds when ", ""));
			_itemPropertyVo.info_unique_type = seekPropertyByValue(["Unique", "Unique-Equipped"]);
			// weapon_xxx
			_itemPropertyVo.weapon_dps = Number(seekPropertyByTag("(", " damage per second)"));
			temporary = seekPropertyByTag("", " Damage");
			if(temporary != "")
			{
				_itemPropertyVo.weapon_min_damage = int(temporary.split(" - ")[0]);
				_itemPropertyVo.weapon_max_damage = int(temporary.split(" - ")[1]);
			}
			_itemPropertyVo.weapon_speed = Number(seekPropertyByTag("Speed ", ""));
			// base_
			_itemPropertyVo.base_armor = int(seekPropertyByTag("", " Armor"));
			_itemPropertyVo.base_strenth = int(seekPropertyByTag("+", " Strength"));
			_itemPropertyVo.base_agility = int(seekPropertyByTag("+", " Agility"));
			_itemPropertyVo.base_stamina = int(seekPropertyByTag("+", " Stamina"));
			_itemPropertyVo.base_intellect = int(seekPropertyByTag("+", " Intellect"));
			_itemPropertyVo.base_spirit = int(seekPropertyByTag("+", " Spirit"));
			// socket_
			while(seekPropertyByValue(["Meta Socket"]) != "")
				_itemPropertyVo.socket_meta++;
			while(seekPropertyByValue(["Red Socket"]) != "")
				_itemPropertyVo.socket_red++;
			while(seekPropertyByValue(["Blue Socket"]) != "")
				_itemPropertyVo.socket_blue++;
			while(seekPropertyByValue(["Yellow Socket"]) != "")
				_itemPropertyVo.socket_yellow++;
			_itemPropertyVo.socket_bonus = seekPropertyByTag("Socket Bonus: ", ""); 
			// general_
			_itemPropertyVo.general_crit_rating = 
				int(new StringProcessor(seekPropertyByTag("critical strike rating by ", "")).interceptNumber());
			_itemPropertyVo.general_hit_rating = 
				int(new StringProcessor(seekPropertyByTag("hit rating by ", "")).interceptNumber());
			_itemPropertyVo.general_haste_rating = 
				int(new StringProcessor(seekPropertyByTag("haste rating by ", "")).interceptNumber());
			// physical_
			_itemPropertyVo.physical_attack_power = 
				int(new StringProcessor(seekPropertyByTag("attack power by ", "")).interceptNumber());
			_itemPropertyVo.physical_armor_penetration = 
				int(new StringProcessor(seekPropertyByTag("armor penetration rating by ", "")).interceptNumber());
			_itemPropertyVo.physical_expertise_rating = 
				int(new StringProcessor(seekPropertyByTag("expertise rating by ", "")).interceptNumber());
			// spell_
			_itemPropertyVo.spell_power = 
				int(new StringProcessor(seekPropertyByTag("spell power by ", "")).interceptNumber());
			_itemPropertyVo.spell_penetration = 
				int(new StringProcessor(seekPropertyByTag("spell penetration by ", "")).interceptNumber());
			_itemPropertyVo.spell_mana_regen = 
				int(seekPropertyByTag("Restores ", " mana per 5 sec"));
			// defense_
			_itemPropertyVo.defense_block_rating = 
				int(new StringProcessor(seekPropertyByTag("block rating by ", "")).interceptNumber());
			_itemPropertyVo.defense_block_value = 
				int(new StringProcessor(seekPropertyByTag("block value of your shield by ", "")).interceptNumber());
			_itemPropertyVo.defense_block_value += int(seekPropertyByTag("", " Block"));
			_itemPropertyVo.defense_defense_rating = 
				int(new StringProcessor(seekPropertyByTag("defense rating by ", "")).interceptNumber());
			_itemPropertyVo.defense_dodge_rating = 
				int(new StringProcessor(seekPropertyByTag("dodge rating by ", "")).interceptNumber());
			_itemPropertyVo.defense_parry_rating = 
				int(new StringProcessor(seekPropertyByTag("parry rating by ", "")).interceptNumber());
			_itemPropertyVo.defense_health_regen = 
				int(seekPropertyByTag("Restores ", " health per 5 sec"));
			_itemPropertyVo.defense_resilience = 
				int(new StringProcessor(seekPropertyByTag("resilience rating by ", "")).interceptNumber());
			// resistance_
			_itemPropertyVo.resistance_arcane = int(seekPropertyByTag("+", " Arcane Resistance"));
			_itemPropertyVo.resistance_shadow = int(seekPropertyByTag("+", " Shadow Resistance"));
			_itemPropertyVo.resistance_nature = int(seekPropertyByTag("+", " Nature Resistance"));
			_itemPropertyVo.resistance_frost = int(seekPropertyByTag("+", " Frost Resistance"));
			_itemPropertyVo.resistance_fire = int(seekPropertyByTag("+", " Fire Resistance"));
			// addition_effect
			var flag:Boolean;
			var array:Array = [];
			for(var i:int = 0; i < _itemDescriptions.length; i++)
			{
				var s:String = _itemDescriptions.getItemAt(i) as String;
				if(flag)
				{
					if(s != "Equip:")
					{
						array.push(s);
						_itemDescriptions.removeItemAt(i);
						i--;
					}
				}
				else
				{
					flag = (s.indexOf("Requires Level ") != -1)
				}
			}
			_itemPropertyVo.addition_effect = array.join(" || ");
			
			gotoNextStep();
		}
		private function seekPropertyByIndex(index:int):String
		{
			var result:String = "";
			
			result = _itemDescriptions.getItemAt(index) as String;
			_itemDescriptions.removeItemAt(0);
			
			return result;
		}
		private function seekPropertyByTag(startTag:String, endTag:String):String
		{
			var result:String = "";
			
			for(var i:int = 0; i < _itemDescriptions.length; i++)
			{
				var s:String = _itemDescriptions.getItemAt(i) as String;
				var value:String;
				try
				{
					value = new StringProcessor(s).intercept(startTag, endTag, false, false);
				}
				catch(error:Error)
				{
					continue;
				}

				result = value;
				_itemDescriptions.removeItemAt(i);
				break;
			}
			return result;
		}
		private function seekPropertyByValue(values:Array):String
		{
			var result:String = "";
			
			for(var i:int = 0; i < _itemDescriptions.length; i++)
			{
				var s:String = _itemDescriptions.getItemAt(i) as String;
				
				for each(var value:String in values)
				{
					if(s == value)
					{
						result = s;
						break;
					}
				}
				if(result != "")
				{
					_itemDescriptions.removeItemAt(i);
					break;
				}
			}
			return result;
		}
		private function translateBindType(value:String):String
		{
			var result:String;

			if(value == "picked up")
				result = "BoP";
			else if(value == "equipped")
				result = "BoE";
			else
				throw new Error("translate info_bind_type -> " + value);
			
			return result;
		}
		private function assignItemVo():void
		{
			_itemVo.slot = seekPropertyByValue(ItemConst.SLOTS);
			if(_itemVo.slot == "")
				this.dispatchEvent(new CollectEvent(CollectEvent.COLLECT_ERROR, _itemVo, _itemPropertyVo, "_itemVo.slot"));
			_itemVo.type = seekPropertyByValue(ItemConst.TYPES);
			if(_itemVo.type == "" && _itemVo.slot != "")
			{
				for each(var type:String in ItemConst.TYPES)
					if(_itemVo.slot == type)
						_itemVo.type = type;
			}
			if(_itemVo.type == "")
				this.dispatchEvent(new CollectEvent(CollectEvent.COLLECT_ERROR, _itemVo, _itemPropertyVo, "_itemVo.type"));
			// fit_(_itemVo.type)
			_itemVo.fit_tank =
				(
				_itemPropertyVo.defense_block_rating > 0
				|| _itemPropertyVo.defense_block_value > 0
				|| _itemPropertyVo.defense_defense_rating > 0
				|| _itemPropertyVo.defense_dodge_rating > 0
				|| _itemPropertyVo.defense_parry_rating > 0
				|| _itemPropertyVo.physical_expertise_rating > 0
				)
			_itemVo.fit_caster = 
				(
				_itemPropertyVo.spell_mana_regen > 0
				|| _itemPropertyVo.spell_power > 0
				)
			_itemVo.fit_melee = 
				(
				_itemPropertyVo.physical_armor_penetration > 0
				|| _itemPropertyVo.physical_attack_power > 0
				|| (
					(_itemPropertyVo.base_strenth > 0 || _itemPropertyVo.base_agility > 0)
					&& !_itemVo.fit_tank && !_itemVo.fit_caster
					)
				)
			if(!_itemVo.fit_tank && _itemVo.fit_caster && _itemVo.fit_melee)
				this.dispatchEvent(new CollectEvent(CollectEvent.COLLECT_ERROR, _itemVo, _itemPropertyVo, "fit_(_itemVo.type)"));
			// fit_(Class)
			initializeClasses();
			var functions:Array = [fitClassBySpecify, fitClassByArmor, fitClassByWeapon, fitClassByOffHand, fitClassByRanged, fitAllClasses]
			for(var i:int = 0; i < functions.length; i++)
			{
				if(!isFitClassSuccess())
				{
					(functions[i] as Function).call(this);
				}
				else
				{
					break;
				}
			}
			if(!isFitClassSuccess())
				this.dispatchEvent(new CollectEvent(CollectEvent.COLLECT_ERROR, _itemVo, _itemPropertyVo, "fit_(Class)"));
			
			gotoNextStep();
		}
		private function fitClassBySpecify():void
		{
			
			var specifyClass:String = seekPropertyByTag("Classes: ", "");
			if(specifyClass != "")
			{
				var array:Array = specifyClass.split(",");
				for each(var classs:String in array)
				{
					classs = StringUtil.trim(classs);
					classs = classs.replace(" ", "");
					_itemVo["fit_" + classs.toLowerCase()] = true;
				}
			}
		}
		private function fitClassByArmor():void
		{
			if(_itemVo.type == "Plate")
			{
				_itemVo.fit_deathknight = true;
				_itemVo.fit_paladin = true;
				_itemVo.fit_warrior = true;
			}
			else if(_itemVo.type == "Mail")
			{
				_itemVo.fit_shaman = true;
				_itemVo.fit_hunter = true;
			}
			else if(_itemVo.type == "Leather")
			{
				_itemVo.fit_druid = true;
				_itemVo.fit_rogue = true;
			}
			else if(_itemVo.type == "Cloth")
			{
				_itemVo.fit_priest = true;
				_itemVo.fit_warlock = true;
				_itemVo.fit_mage = true;
			}
		}
		private function fitClassByWeapon():void
		{
			// Death Knight: Axes, Polearms, Swords, Two-Handed Axes, Two-Handed Swords, One-handed Maces, Two-Handed Maces
			// Druid: Staves, Polearms, Maces (with training), Daggers (with training), Unarmed Weapons (with training)
			// Hunter: Axes (Dwarves/Tauren start, others with training), Daggers (Night Elves and Blood Elves start, others with training), Guns or Bows, Crossbows (Draenei start, others with training), Fist Weapons (with training), Polearms (with training), Staves (with training), Swords (Draenei start, others with training), Thrown (with training), Two-Handed Axes (with training), Two-Handed Swords (with training)
			// Mage: Staves, Wands, Daggers (with training), Swords (with training)
			// Paladin: One- and Two-handed Maces, One- and Two-handed Swords (with training), One- and Two-handed Axes, Polearms (with training)
			// Priest: One-Handed Maces, Daggers, Staves, Wands
			// Rogue: Daggers, Thrown, Swords (with training), Bows (with training), Crossbows (with training), Maces (with training), Fist Weapons (with training), Guns (with training)
			// Shaman: One-Handed Maces, Staves, Fist Weapons (Draenei with training), One-Handed Axes (with training), Daggers (with training), Two-Handed Axes (with training), Two-Handed Maces (with training)
			// Warlock: Daggers, Wands, Swords (with training), Staves (with training)
			// Warrior: All (excluding wands)
			if(_itemVo.slot == "Main Hand" || _itemVo.slot == "Off Hand" || _itemVo.slot == "One-Hand")
			{
				if(_itemVo.type == "Axe")
				{
					_itemVo.fit_deathknight = true;
					_itemVo.fit_hunter = true;
					_itemVo.fit_paladin = true;
					_itemVo.fit_shaman = true;
					_itemVo.fit_warrior = true;
				}
				else if(_itemVo.type == "Mace")
				{
					_itemVo.fit_deathknight = true;
					_itemVo.fit_druid = true;
					_itemVo.fit_paladin = true;
					_itemVo.fit_priest = true;
					_itemVo.fit_rogue = true;
					_itemVo.fit_shaman = true;
					_itemVo.fit_warrior = true;
				}
				else if(_itemVo.type == "Sword")
				{
					_itemVo.fit_deathknight = true;
					_itemVo.fit_hunter = true;
					_itemVo.fit_paladin = true;
					_itemVo.fit_mage = true;
					_itemVo.fit_warlock = true;
					_itemVo.fit_rogue = true;
					_itemVo.fit_warrior = true;
				}
				else if(_itemVo.type == "Fist Weapon")
				{
					_itemVo.fit_hunter = true;
					_itemVo.fit_rogue = true;
					_itemVo.fit_shaman = true;
					_itemVo.fit_warrior = true;
					_itemVo.fit_druid = true;
				}
				else if(_itemVo.type == "Dagger")
				{
					_itemVo.fit_warrior = true;
					_itemVo.fit_shaman = true;
					_itemVo.fit_hunter = true;
					_itemVo.fit_druid = true;
					_itemVo.fit_rogue = true;
					_itemVo.fit_priest = true;
					_itemVo.fit_warlock = true;
					_itemVo.fit_mage = true;
				}
			}
			else if(_itemVo.slot == "Two-Hand")
			{
				if(_itemVo.type == "Axe")
				{
					_itemVo.fit_deathknight = true;
					_itemVo.fit_hunter = true;
					_itemVo.fit_paladin = true;
					_itemVo.fit_shaman = true;
				}
				else if(_itemVo.type == "Mace")
				{
					_itemVo.fit_deathknight = true;
					_itemVo.fit_druid = true;
					_itemVo.fit_paladin = true;
					_itemVo.fit_shaman = true;
				}
				else if(_itemVo.type == "Sword")
				{
					_itemVo.fit_deathknight = true;
					_itemVo.fit_hunter = true;
					_itemVo.fit_paladin = true;
					_itemVo.fit_warrior = true;
				}
				else if(_itemVo.type == "Polearm")
				{
					_itemVo.fit_deathknight = true;
					_itemVo.fit_paladin = true;
					_itemVo.fit_warrior = true;
					_itemVo.fit_hunter = true;
					_itemVo.fit_druid = true;
				}
				else if(_itemVo.type == "Staff")
				{
					_itemVo.fit_hunter = true;
					_itemVo.fit_druid = true;
					_itemVo.fit_mage = true;
					_itemVo.fit_priest = true;
					_itemVo.fit_shaman = true;
					_itemVo.fit_warlock = true;
				}
			}
		}
		private function fitClassByOffHand():void
		{
			if(_itemVo.type == "Shield")
			{
				_itemVo.fit_paladin = true;
				_itemVo.fit_warrior = true;
				_itemVo.fit_shaman = true;
			}
			else if(_itemVo.type == "Held In Off-hand")
			{
				_itemVo.fit_priest = true;
				_itemVo.fit_warlock = true;
				_itemVo.fit_mage = true;
			}
		}
		private function fitClassByRanged():void
		{
			if(_itemVo.type == "Gun"
				|| _itemVo.type == "Bow"
				|| _itemVo.type == "Thrown"
				|| _itemVo.type == "Crossbow")
			{
				_itemVo.fit_hunter = true;
				_itemVo.fit_rogue = true;
				_itemVo.fit_warrior = true;
			}
			else if(_itemVo.type == "Wand")
			{
				_itemVo.fit_priest = true;
				_itemVo.fit_warlock = true;
				_itemVo.fit_mage = true;
			}
			else if(_itemVo.type == "Idol")
			{
				_itemVo.fit_druid = true;
			}
			else if(_itemVo.type == "Libram")
			{
				_itemVo.fit_paladin = true;
			}
			else if(_itemVo.type == "Totem")
			{
				_itemVo.fit_shaman = true;
			}
			else if(_itemVo.type == "Sigil")
			{
				_itemVo.fit_deathknight = true;
			}
		}
		private function fitAllClasses():void
		{
			if(_itemVo.slot == "Finger" 
				|| _itemVo.slot == "Trinket" 
				|| _itemVo.slot == "Neck" 
				|| _itemVo.slot == "Back")
			{
				_itemVo.fit_deathknight = true;
				_itemVo.fit_paladin = true;
				_itemVo.fit_warrior = true;
				_itemVo.fit_shaman = true;
				_itemVo.fit_hunter = true;
				_itemVo.fit_druid = true;
				_itemVo.fit_rogue = true;
				_itemVo.fit_priest = true;
				_itemVo.fit_warlock = true;
				_itemVo.fit_mage = true;
			}
		}
		private function initializeClasses():void
		{
			_itemVo.fit_deathknight = false;
			_itemVo.fit_paladin = false;
			_itemVo.fit_warrior = false;
			_itemVo.fit_shaman = false;
			_itemVo.fit_hunter = false;
			_itemVo.fit_druid = false;
			_itemVo.fit_rogue = false;
			_itemVo.fit_priest = false;
			_itemVo.fit_warlock = false;
			_itemVo.fit_mage = false;
		}
		
		private function isFitClassSuccess():Boolean
		{
			return _itemVo.fit_deathknight
				|| _itemVo.fit_paladin
				|| _itemVo.fit_warrior
				|| _itemVo.fit_shaman
				|| _itemVo.fit_hunter
				|| _itemVo.fit_druid
				|| _itemVo.fit_rogue
				|| _itemVo.fit_priest
				|| _itemVo.fit_warlock
				|| _itemVo.fit_mage;
		}
		private function dropTrash():void
		{
			seekPropertyByValue(["Heroic"]);
			while(seekPropertyByValue(["Equip:"]) != "")
				;
			seekPropertyByTag("Durability ", "");
			seekPropertyByTag("Requires Level ", "");
			seekPropertyByTag("", "feral attack power");
			seekPropertyByTag("Races: ", "");
			
			gotoNextStep();
		}
		private function updateDB():void
		{
			// TblItem - update
			TblItem_DAO.getInstance().updateRow(_itemVo, tblItemUpdateHandler);
		}
		private function tblItemUpdateHandler(rowItem:TblItemVO):void
		{
			// TblItemProperty - delete
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = DBConst.armoryConn;
			stmt.text = "delete from TblItemProperty where info_item_id = @item_id ";
			stmt.parameters["@item_id"] = _itemVo.item_id;
			stmt.addEventListener(SQLEvent.RESULT, itemPropertyDeleteHandler);
			stmt.execute();
		}
		private function itemPropertyDeleteHandler(event:SQLEvent):void
		{
			// TblItemProperty - insert
			TblItemProperty_DAO.getInstance().insertRow(_itemPropertyVo, itemPropertyInsertHandler);
		}
		private function itemPropertyInsertHandler(rowItem:TblItemPropertyVO):void
		{
			gotoNextStep();
		}
	}
}